import { Parameter } from "./Parameter";
import { must, any } from "../../core/logic";
import { checkTypedArrayType,VertexFormat } from "../../core/utils";
import { Engine } from "../../Engine";
class Vertex extends Parameter {
    constructor(opts={}){
        super(opts);
        this.gpu = {
            buffer: null,
            layout: null,
            entry: null
        }
        if(opts.buffer){
            this.gpu.buffer=opts.buffer
            this.gpu.layout={
                arrayStride: opts.buffer.arrayStride,
                stepMode: opts.buffer.stepMode,
                attributes:opts.buffer.attributes,
            };
            this.stepMode=opts.buffer.stepMode
            this.size=opts.buffer.size
            this.usage=opts.buffer.usage
            this.itemLength=opts.buffer.arrayStride
        }else{
            this.size = any(opts.size, 0);
            this.usage = any(opts.usage, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST);
            this.itemLength = any(opts.itemLength,12);
            this.data = must(opts.data);
            this.stepMode = any(opts.stepMode, 'vertex');
            this.updateBuffer();
            this.updateBufferLayout();
        }

        // this.updateBufferEntry();
    }
    set size(v) {
        this._size = v;
        return this._size;
    }
    get size() {
        return this._size;
    }
    set usage(v) {
        this._usage = v;
        return this._usage;
    }
    get usage() {
        return this._usage;
    }
    set itemLength(v) {
        this._itemLength = v;
        return this._itemLength;
    }
    get itemLength() {
        return this._itemLength;
    }
    set data(v) {
        this._data = v;
        return this._data;
    }
    get data() {
        return this._data;
    }

    updateBuffer() {
        if (!this.gpu.buffer) {
            this.gpu.buffer = Engine.instance.device.createBuffer({
                label: this.name,
                size: this.size,
                usage: this.usage,
                // mappedAtCreation?
            })
            Engine.instance.device.queue.writeBuffer(this.gpu.buffer, /*bufferOffset=*/0, this.data);
            this.bufferDataType=this.data.constructor.name
            this.length=this.data.length
        }
    }
    buffer(data){
        Engine.instance.device.queue.writeBuffer(this.gpu.buffer, /*bufferOffset=*/0, data);
    }
    updateBufferLayout() {
        if (!this.gpu.layout) {
            this.gpu.layout = {
                arrayStride: this.itemLength * this.data.BYTES_PER_ELEMENT,
                stepMode: this.stepMode,
                attributes: [{
                    format: `${checkTypedArrayType(this.data)}`+VertexFormat[this.itemLength], // "float32x2",
                    offset: 0,
                    shaderLocation: this.binding
                }],
            };
        }
        delete this._data
    }
    updateBufferEntry() {
        if (!this.gpu.entry) {
            this.gpu.entry = {
                binding: this.binding,
                resource: { buffer: this.gpu.buffer }
            }
        }
        delete this._data
    }
    update() {
        // this.updateBuffer();
        // this.updateBufferLayout();
        // this.updateBufferEntry();
    }
    destroy() {
        if(this.watchers.length<=0){//没有被引用则销毁
            super.destroy();
            if (this.gpu && this.gpu.buffer) {
                this.gpu.buffer.destroy();
                this.gpu.buffer = null;
            }
            delete this._data
            if (this.gpu && this.gpu.layout) {
                this.gpu.layout = null;
            }
            this.gpu=null;
            return true;
        }
        return false;
    }

}
export { Vertex }
